﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.EventSystems;
using System;
using UnityEngine.UI;
using XLua;

public class HUIManager : Singleton<HUIManager> {

	private List<HUIFormScript> m_forms;

	private List<HUIFormScript> m_pooledForms;

	private int m_formSequence;

	private List<int> m_existFormSequences;

	private EventSystem m_uiInputEventSystem;

	private GameObject m_uiRoot;

	private Camera m_formCamera;

	private bool m_needSortForms;

	private bool m_needUpdateRaycasterAndHide;

	#region init
	public override void Init()
	{
		this.m_forms = new List<HUIFormScript> ();
		this.m_pooledForms = new List<HUIFormScript> ();
		this.m_formSequence = 0;
		this.m_existFormSequences = new List<int>();
		this.CreateUIRoot ();
		this.CreateEventSystem ();
		this.CreateCamera ();

		HUIEventManager.Instance.AddUIEventListener(enUIEventID.UI_OnFormVisibleChanged, new HUIEventManager.OnUIEventHandler(this.OnFormVisibleChanged));
		HUIEventManager.Instance.AddUIEventListener(enUIEventID.UI_OnFormPriorityChanged, new HUIEventManager.OnUIEventHandler(this.OnFormPriorityChanged));
	}

	private void CreateUIRoot()
	{
		this.m_uiRoot = new GameObject("CUIManager");
		GameObject.DontDestroyOnLoad (this.m_uiRoot);
	}

	private void CreateEventSystem()
	{
		this.m_uiInputEventSystem = UnityEngine.Object.FindObjectOfType<EventSystem>();                                     
		if (this.m_uiInputEventSystem == null)
		{
			GameObject gameObject = new GameObject("EventSystem");
			this.m_uiInputEventSystem = gameObject.AddComponent<EventSystem>();
			gameObject.AddComponent<StandaloneInputModule>();
		}
		this.m_uiInputEventSystem.gameObject.transform.parent = this.m_uiRoot.transform;
	}

	private void CreateCamera()
	{
		GameObject gameObject = new GameObject("Camera_Form");
		gameObject.transform.SetParent(this.m_uiRoot.transform, true);
		gameObject.transform.localPosition = Vector3.zero;
		gameObject.transform.localRotation = Quaternion.identity;
		gameObject.transform.localScale = Vector3.one;
		Camera camera = gameObject.AddComponent<Camera>();
		camera.orthographic = true;
		camera.orthographicSize = 50f;
		camera.clearFlags = CameraClearFlags.Depth;
		camera.cullingMask = 1 << LayerMask.NameToLayer("UI");
		camera.depth = 10f;
		this.m_formCamera = camera;
	}
	#endregion


	public void Update() {
		for (int i = 0; i < this.m_forms.Count; i++)
		{
			this.m_forms[i].CustomUpdate();
			if (this.m_forms[i].IsNeedClose())
			{
				if (this.m_forms[i].TurnToClosed(false))
				{
					this.RecycleForm(i);
					this.m_needSortForms = true;
					continue;
				}
			}
			else if (this.m_forms[i].IsClosed() && !this.m_forms[i].IsInFadeOut())
			{
				this.RecycleForm(i);
				this.m_needSortForms = true;
				continue;
			}
		}
		if (this.m_needSortForms)
		{
			this.ProcessFormList(true, true);
		}
		else if (this.m_needUpdateRaycasterAndHide)
		{
			this.ProcessFormList(false, true);
		}
		this.m_needSortForms = false;
		this.m_needUpdateRaycasterAndHide = false;
	}

	public void LateUpdate()
	{
		for (int i = 0; i < this.m_forms.Count; i++)
		{
			this.m_forms[i].CustomLateUpdate();
		}
	}

	#region form
	private void RecycleForm(int formIndex)
	{
		this.RemoveFromExistFormSequenceList(this.m_forms[formIndex].GetSequence());
		this.RecycleForm(this.m_forms[formIndex]);
		this.m_forms.RemoveAt(formIndex);
	}

	private void RecycleForm(HUIFormScript formScript)
	{
		if (formScript == null)
		{
			return;
		}
		if (formScript.m_useFormPool)
		{
			formScript.Hide(true);
			this.m_pooledForms.Add(formScript);
		}
		else
		{
			try
			{
				if (formScript.m_canvasScaler != null)
				{
					formScript.m_canvasScaler.enabled = false;
				}
				UnityEngine.Object.Destroy(formScript.gameObject);
			}
			catch (Exception ex)
			{
				Debug.AssertFormat(false, "Error destroy {0} formScript gameObject: message: {1}, callstack: {2}", new object[]
				{
					formScript.name,
					ex.Message,
					ex.StackTrace
				});
			}
		}
	}

	private GameObject CreateForm(string formPrefabPath, bool useFormPool)
	{
		GameObject gameObject = null;
		if (useFormPool)
		{
			for (int i = 0; i < this.m_pooledForms.Count; i++)
			{
				if (string.Equals(formPrefabPath, this.m_pooledForms[i].m_formPath, StringComparison.OrdinalIgnoreCase))
				{
					this.m_pooledForms[i].Appear(true);
					gameObject = this.m_pooledForms[i].gameObject;
					this.m_pooledForms.RemoveAt(i);
					break;
				}
			}
		}
		if (gameObject == null)
		{
			GameObject gameObject2 = (GameObject)ResourceManager.Instance.GetResource(formPrefabPath, typeof(GameObject), enResourceType.UIForm, false, false).m_content;
			if (gameObject2 == null)
			{
				return null;
			}
			gameObject = (GameObject)UnityEngine.Object.Instantiate(gameObject2);
		}
		if (gameObject != null)
		{
			HUIFormScript component = gameObject.GetComponent<HUIFormScript>();
			if (component != null)
			{
				component.m_useFormPool = useFormPool;
			}
		}
		return gameObject;
	}


	public void RemoveFromExistFormSequenceList(int formSequence)
	{
		if (this.m_existFormSequences != null)
		{
			this.m_existFormSequences.Remove(formSequence);
		}
	}

	public void AddToExistFormSequenceList(int formSequence)
	{
		if (this.m_existFormSequences != null)
		{
			this.m_existFormSequences.Add(formSequence);
		}
	}

	private void ProcessFormList(bool sort, bool handleInputAndHide)
	{
		if (sort)
		{
			this.m_forms.Sort();
			for (int i = 0; i < this.m_forms.Count; i++)
			{
				int formOpenOrder = this.GetFormOpenOrder(this.m_forms[i].GetSequence());
				this.m_forms[i].SetDisplayOrder(formOpenOrder);
			}
		}
		if (handleInputAndHide)
		{
			this.UpdateFormHided();
			this.UpdateFormRaycaster();
		}
	}

	public int GetFormOpenOrder(int formSequence)
	{
		int num = this.m_existFormSequences.IndexOf(formSequence);
		return (num < 0) ? 0 : (num + 1);
	}

	private void UpdateFormRaycaster()
	{
		bool flag = true;
		for (int i = this.m_forms.Count - 1; i >= 0; i--)
		{
			if (!this.m_forms[i].m_disableInput && !this.m_forms[i].IsHided())
			{
				GraphicRaycaster graphicRaycaster = this.m_forms[i].GetGraphicRaycaster();
				if (graphicRaycaster != null)
				{
					graphicRaycaster.enabled = flag;
				}
				if (this.m_forms[i].m_isBlock && flag)
				{
					flag = false;
				}
			}
		}
	}

	private void UpdateFormHided()
	{
		bool flag = false;
		for (int i = this.m_forms.Count - 1; i >= 0; i--)
		{
			if (flag)
			{
				this.m_forms[i].Hide(false);
			}
			else
			{
				this.m_forms[i].Appear(false);
			}
			if (!flag && !this.m_forms[i].IsHided() && this.m_forms[i].m_hideUnderForms)
			{
				flag = true;
			}
		}
	}
	#endregion

	#region open close forms
	public HUIFormScript OpenForm(string formPath, bool useFormPool, bool useCameraRenderMode = true)
	{
		HUIFormScript hUIFormScript = this.GetUnClosedForm(formPath);
		if (hUIFormScript != null && hUIFormScript.m_isSingleton)
		{
			this.RemoveFromExistFormSequenceList(hUIFormScript.GetSequence());
			this.AddToExistFormSequenceList(this.m_formSequence);
			int formOpenOrder = this.GetFormOpenOrder(this.m_formSequence);
			hUIFormScript.Open(this.m_formSequence, true, formOpenOrder);
			this.m_formSequence++;
			this.m_needSortForms = true;
			return hUIFormScript;
		}
		GameObject gameObject = this.CreateForm(formPath, useFormPool);
		if (gameObject == null)
		{
			return null;
		}
		if (!gameObject.activeSelf)
		{
			gameObject.SetActive(true);
		}
		string formName = this.GetFormName(formPath);
		gameObject.name = formName;
		if (gameObject.transform.parent != this.m_uiRoot.transform)
		{
			gameObject.transform.SetParent(this.m_uiRoot.transform);
		}
		hUIFormScript = gameObject.GetComponent<HUIFormScript>();
		if (hUIFormScript != null)
		{
			this.AddToExistFormSequenceList(this.m_formSequence);
			int formOpenOrder2 = this.GetFormOpenOrder(this.m_formSequence);
			hUIFormScript.Open(formPath, (!useCameraRenderMode) ? null : this.m_formCamera, this.m_formSequence, false, formOpenOrder2);
			this.m_forms.Add(hUIFormScript);
		}
		this.m_formSequence++;
		this.m_needSortForms = true;
		return hUIFormScript;
	}

	private string GetFormName(string formPath)
	{
		return FileTools.EraseExtension(FileTools.GetFullName(formPath));
	}

	public HUIFormScript GetForm(string formPath)
	{
		for (int i = 0; i < this.m_forms.Count; i++)
		{
			if (this.m_forms[i].m_formPath.Equals(formPath) && !this.m_forms[i].IsNeedClose() && !this.m_forms[i].IsClosed())
			{
				return this.m_forms[i];
			}
		}
		return null;
	}

	public HUIFormScript GetForm(int formSequence)
	{
		for (int i = 0; i < this.m_forms.Count; i++)
		{
			if (this.m_forms[i].GetSequence() == formSequence && !this.m_forms[i].IsNeedClose() && !this.m_forms[i].IsClosed())
			{
				return this.m_forms[i];
			}
		}
		return null;
	}

	public HUIFormScript GetTopForm()
	{
		HUIFormScript cUIFormScript = null;
		for (int i = 0; i < this.m_forms.Count; i++)
		{
			if (this.m_forms[i] != null)
			{
				if (cUIFormScript == null)
				{
					cUIFormScript = this.m_forms[i];
				}
				else if (this.m_forms[i].GetSortingOrder() > cUIFormScript.GetSortingOrder())
				{
					cUIFormScript = this.m_forms[i];
				}
			}
		}
		return cUIFormScript;
	}

	private HUIFormScript GetUnClosedForm(string formPath)
	{
		for (int i = 0; i < this.m_forms.Count; i++)
		{
			if (this.m_forms[i].m_formPath.Equals(formPath) && !this.m_forms[i].IsClosed())
			{
				return this.m_forms[i];
			}
		}
		return null;
	}

	public List<HUIFormScript> GetForms()
	{
		return this.m_forms;
	}

	public void CloseForm(string formPath)
	{
		for (int i = 0; i < this.m_forms.Count; i++)
		{
			if (string.Equals(this.m_forms[i].m_formPath, formPath))
			{
				this.m_forms[i].Close();
			}
		}
	}

	public void CloseForm(HUIFormScript formScript)
	{
		for (int i = 0; i < this.m_forms.Count; i++)
		{
			if (this.m_forms[i] == formScript)
			{
				this.m_forms[i].Close();
			}
		}
	}

	public void CloseForm(int formSequence)
	{
		for (int i = 0; i < this.m_forms.Count; i++)
		{
			if (this.m_forms[i].GetSequence() == formSequence)
			{
				this.m_forms[i].Close();
			}
		}
	}

	public void CloseAllForm(string[] exceptFormNames = null, bool closeImmediately = true, bool clearFormPool = true)
	{
		for (int i = 0; i < this.m_forms.Count; i++)
		{
			bool flag = true;
			if (exceptFormNames != null)
			{
				for (int j = 0; j < exceptFormNames.Length; j++)
				{
					if (string.Equals(this.m_forms[i].m_formPath, exceptFormNames[j]))
					{
						flag = false;
						break;
					}
				}
			}
			if (flag)
			{
				this.m_forms[i].Close();
			}
		}
		if (closeImmediately)
		{
			int k = 0;
			while (k < this.m_forms.Count)
			{
				if (this.m_forms[k].IsNeedClose() || this.m_forms[k].IsClosed())
				{
					if (this.m_forms[k].IsNeedClose())
					{
						this.m_forms[k].TurnToClosed(true);
					}
					this.RecycleForm(k);
				}
				else
				{
					k++;
				}
			}
			if (exceptFormNames != null)
			{
				this.ProcessFormList(true, true);
			}
		}
		if (clearFormPool)
		{
			this.ClearFormPool();
		}
	}

	public void ClearFormPool()
	{
		for (int i = 0; i < this.m_pooledForms.Count; i++)
		{
			UnityEngine.Object.Destroy(this.m_pooledForms[i].gameObject);
		}
		this.m_pooledForms.Clear();
	}

	#endregion

	public bool HasForm()
	{
		return this.m_forms.Count > 0;
	}

	public void DisableInput()
	{
		if (this.m_uiInputEventSystem != null)
		{
			this.m_uiInputEventSystem.gameObject.SetActive(false);
		}
	}

	public void EnableInput()
	{
		if (this.m_uiInputEventSystem != null)
		{
			this.m_uiInputEventSystem.gameObject.SetActive(true);
		}
	}

	public EventSystem GetEventSystem()
	{
		return this.m_uiInputEventSystem;
	}

	private void OnFormVisibleChanged(HUIEvent uiEvent)
	{
		this.m_needUpdateRaycasterAndHide = true;
	}

	private void OnFormPriorityChanged(HUIEvent uiEvent)
	{
		this.m_needSortForms = true;
	}
}
